home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / Miro_Downloader.exe / moviedata.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-11-12  |  6.1 KB  |  200 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. from eventloop import asIdle
  5. from platformutils import FilenameType
  6. import os.path as os
  7. import re
  8. import subprocess
  9. import time
  10. import traceback
  11. import threading
  12. import Queue
  13. import app
  14. import eventloop
  15. import logging
  16. import config
  17. import prefs
  18. import util
  19. MOVIE_DATA_UTIL_TIMEOUT = 60
  20. SLEEP_DELAY = 0.1
  21. durationRE = re.compile('Miro-Movie-Data-Length: (\\d+)')
  22. thumbnailSuccessRE = re.compile('Miro-Movie-Data-Thumbnail: Success')
  23. thumbnailRE = re.compile('Miro-Movie-Data-Thumbnail: (Success|Failure)')
  24.  
  25. def thumbnailDirectory():
  26.     dir = os.path.join(config.get(prefs.ICON_CACHE_DIRECTORY), 'extracted')
  27.     
  28.     try:
  29.         os.makedirs(dir)
  30.     except:
  31.         pass
  32.  
  33.     return dir
  34.  
  35.  
  36. class MovieDataInfo:
  37.     """Little utility class to keep track of data associated with each movie.
  38.     This is:
  39.  
  40.     * The item.
  41.     * The path to the video.
  42.     * Path to the thumbnail we're trying to make.
  43.     * List of commands that we're trying to run, and their environments.
  44.     """
  45.     
  46.     def __init__(self, item):
  47.         self.item = item
  48.         self.videoPath = item.getVideoFilename()
  49.         thumbnailFilename = '%s.%s.png' % (os.path.basename(self.videoPath), util.random_string(5))
  50.         self.thumbnailPath = os.path.join(thumbnailDirectory(), thumbnailFilename)
  51.         self.programInfo = []
  52.         if hasattr(app, 'controller') and hasattr(app.controller, 'videoDisplay'):
  53.             for renderer in app.controller.videoDisplay.renderers:
  54.                 
  55.                 try:
  56.                     (commandLine, env) = renderer.movieDataProgramInfo(self.videoPath, self.thumbnailPath)
  57.                 except NotImplementedError:
  58.                     continue
  59.  
  60.                 self.programInfo.append((commandLine, env))
  61.             
  62.         
  63.  
  64.  
  65.  
  66. class MovieDataUpdater:
  67.     
  68.     def __init__(self):
  69.         self.inShutdown = False
  70.         self.queue = Queue.Queue()
  71.         self.thread = None
  72.  
  73.     
  74.     def startThread(self):
  75.         self.thread = threading.Thread(name = 'Movie Data Thread', target = self.threadLoop)
  76.         self.thread.setDaemon(True)
  77.         self.thread.start()
  78.  
  79.     
  80.     def threadLoop(self):
  81.         while not self.inShutdown:
  82.             movieDataInfo = self.queue.get(block = True)
  83.             if movieDataInfo is None:
  84.                 break
  85.             
  86.             
  87.             try:
  88.                 duration = -1
  89.                 screenshotWorked = False
  90.                 screenshot = None
  91.                 for commandLine, env in movieDataInfo.programInfo:
  92.                     stdout = self.runMovieDataProgram(commandLine, env)
  93.                     if duration == -1:
  94.                         duration = self.parseDuration(stdout)
  95.                     
  96.                     if thumbnailSuccessRE.search(stdout):
  97.                         screenshotWorked = True
  98.                     
  99.                     if duration != -1 and screenshotWorked:
  100.                         break
  101.                         continue
  102.                 
  103.                 if screenshotWorked and os.path.exists(movieDataInfo.thumbnailPath):
  104.                     screenshot = movieDataInfo.thumbnailPath
  105.                 else:
  106.                     screenshot = FilenameType('')
  107.                 self.updateFinished(movieDataInfo.item, duration, screenshot)
  108.             continue
  109.             if self.inShutdown:
  110.                 break
  111.             
  112.  
  113.             util.failedExn('When running external movie data program')
  114.             self.updateFinished(movieDataInfo.item, -1, None)
  115.             continue
  116.  
  117.     
  118.     def runMovieDataProgram(self, commandLine, env):
  119.         start_time = time.time()
  120.         pipe = subprocess.Popen(commandLine, stdout = subprocess.PIPE, stdin = subprocess.PIPE, stderr = subprocess.PIPE, env = env, startupinfo = util.no_console_startupinfo())
  121.         while pipe.poll() is None and not (self.inShutdown):
  122.             time.sleep(SLEEP_DELAY)
  123.             if time.time() - start_time > MOVIE_DATA_UTIL_TIMEOUT:
  124.                 logging.info('Movie data process hung, killing it')
  125.                 self.killProcess(pipe.pid)
  126.                 return ''
  127.                 continue
  128.         if self.inShutdown:
  129.             if pipe.poll() is None:
  130.                 logging.info('Movie data process running after shutdown, killing it')
  131.                 self.killProcess(pipe.pid)
  132.             
  133.             return ''
  134.         
  135.         return pipe.stdout.read()
  136.  
  137.     
  138.     def killProcess(self, pid):
  139.         
  140.         try:
  141.             app.delegate.killProcess(pid)
  142.         except:
  143.             logging.warn('Error trying to kill the movie data process:\n%s', traceback.format_exc())
  144.  
  145.         logging.info('Movie data process killed')
  146.  
  147.     
  148.     def outputValid(self, stdout):
  149.         if thumbnailRE.search(stdout) is not None:
  150.             pass
  151.         return durationRE.search(stdout) is not None
  152.  
  153.     
  154.     def parseDuration(self, stdout):
  155.         durationMatch = durationRE.search(stdout)
  156.         if durationMatch:
  157.             return int(durationMatch.group(1))
  158.         else:
  159.             return -1
  160.  
  161.     
  162.     def updateFinished(self, item, duration, screenshot):
  163.         if item.idExists():
  164.             item.duration = duration
  165.             item.screenshot = screenshot
  166.             item.updating_movie_info = False
  167.             item.resizeScreenshot()
  168.             item.signalChange()
  169.         
  170.  
  171.     updateFinished = asIdle(updateFinished)
  172.     
  173.     def requestUpdate(self, item):
  174.         if self.inShutdown:
  175.             return None
  176.         
  177.         filename = item.getVideoFilename()
  178.         if not filename or not os.path.isfile(filename):
  179.             return None
  180.         
  181.         if item.downloader and not item.downloader.isFinished():
  182.             return None
  183.         
  184.         if item.updating_movie_info:
  185.             return None
  186.         
  187.         item.updating_movie_info = True
  188.         self.queue.put(MovieDataInfo(item))
  189.  
  190.     
  191.     def shutdown(self):
  192.         self.inShutdown = True
  193.         self.queue.put(None)
  194.         if self.thread is not None:
  195.             self.thread.join()
  196.         
  197.  
  198.  
  199. movieDataUpdater = MovieDataUpdater()
  200.